using System;
using System.Collections.Generic;
using System.Text;
using VIX.Enums;
using VixCOM;

namespace VIX
{
    public class PropertyList : IDisposable
    {
        #region Private Fields
        private IPropertyList propHandle;
        #endregion

        #region Constructor/Destructor
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyList"/> class. Pass the IPropertyList handle referencing the property list as a parameter.
        /// </summary>
        /// <param name="propertyList">The IPropertyList handle to the property list.</param>
        internal PropertyList(IPropertyList propertyList)
        {
            propHandle = propertyList;
        }

        /// <summary>
        /// Finalizes an instance of the <see cref="PropertyList"/> class.
        /// </summary>
        ~PropertyList()
        {
            Dispose();
        }

        public void Dispose()
        {
            propHandle = null;

            GC.SuppressFinalize(this);
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the underlying VIX handle.
        /// </summary>
        /// <value>The underlying VIX handle.</value>
        internal IPropertyList Handle
        {
            get { return this.propHandle; }
        }
        #endregion

        #region VIX-API functions
        /// <summary>
        /// Retrieves property data for the property identified by propertyID.
        /// </summary>
        /// <param name="propertyID">This identifies which property to fetch.</param>
        /// <returns>The property data corresponding to the propertyID requested after the function call is complete.</returns>
        public object GetProperty(VIX_PROPERTY propertyID)
        {
            object propertyData;

            ulong err = this.propHandle.GetProperty((int)propertyID, out propertyData);

            VixCOMWrapper.Instance.CheckForError(err);

            return propertyData;
        }

        /// <summary>
        /// Sets the data for the property identified by propertyID.
        /// </summary>
        /// <param name="propertyID">This identifies which property to set.</param>
        /// <param name="propertyData">The property identified by propertyID will be set to this data.</param>
        public void SetProperty(VIX_PROPERTY propertyID, object propertyData)
        {
            ulong err = this.propHandle.SetProperty((int)propertyID, propertyData);

            VixCOMWrapper.Instance.CheckForError(err);
        }

        /// <summary>
        /// This method allows you to get one or more properties from the PropertyList. For a list of property IDs, see <see cref="VIX_PROPERTY"/>.
        /// </summary>
        /// <remarks>
        /// <list type="bullet"> 
        /// <item>This function allows you to get one or more properties from the PropertyList, but only specific properties may be defined for this object.</item>
        /// <item>The value of <see cref="VIX_PROPERTY.VM_TOOLS_STATE"/> is valid only after calling <see cref="VM.WaitForToolsInGuest"/>.</item>
        /// </list>
        /// </remarks>
        /// <exception cref="VixException">Thrown when a VIX-API function returns an error.</exception>
        /// <param name="propertyIDs">An array of property-IDs to identify the properties to fetch.</param>
        /// <returns>A <see cref="System.Collections.Generic.List{T}"/> object that stores the properties identified by the array <paramref name="propertyIDs"/>. Each element in <paramref name="propertyIDs"/> matches the corresponding indentifier in the returned <see cref="System.Collections.Generic.List{T}"/>; for example, if the first element in the <paramref name="propertyIDs"/> array is <see cref="VIX_PROPERTY.SNAPSHOT_DISPLAYNAME"/>, the first element in the <see cref="System.Collections.Generic.List{T}"/> will be the object that is the result of this job, if one exists.</returns>
        public List<object> GetProperties(VIX_PROPERTY[] propertyIDs)
        {
            return VixCOMWrapper.Instance.GetProperties(this.propHandle, propertyIDs);
        }
        #endregion
    }
}
